package com.juyu.miliao.api.util;

import org.springframework.util.StringUtils;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

/**
 * @author jh
 * 2018/8/16
 */
public class DateUtil {

    /**
     * 通用sdf
     */
    private static final SimpleDateFormat COMMON_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * sdf有线程安全问题,可用threadLocal
     */
    private static ThreadLocal<DateFormat> threadLocal = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));


    private DateUtil() {
        throw new RuntimeException("illegal new utils");
    }

    /**
     * 格式化String转date
     *
     * @param dateStr string
     * @return date
     */
    public static Date parseSimple(String dateStr) {
        Date date = null;
        try {
            date = threadLocal.get().parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        threadLocal.remove();
        return date;
    }

    /**
     * 格式化date
     *
     * @param date date
     * @return string
     */
    public static String formatSimple(Date date) {
        String s = threadLocal.get().format(date);
        threadLocal.remove();
        return s;
    }

    /**
     * 通用format
     *
     * @param date date
     * @return String
     */
    public static String formatCommon(Date date) {
        synchronized (COMMON_FORMAT) {
            return COMMON_FORMAT.format(date);
        }
    }

    /**
     * 通用parse
     *
     * @param s string
     * @return date
     */
    public static Date parseCommon(String s) {
        Date date = null;
        if (!StringUtils.isEmpty(s)) {
            synchronized (COMMON_FORMAT) {
                try {
                    date = COMMON_FORMAT.parse(s);
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
        }

        return date;
    }

    /**
     * 自定义parse
     *
     * @param s            待格式化字符串
     * @param formatString 格式化规则
     * @return date
     */
    public static Date parse(String s, String formatString) {
        SimpleDateFormat sdf = new SimpleDateFormat(formatString);
        Date date = null;
        try {
            date = sdf.parse(s);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * 自定义format
     *
     * @param date         date
     * @param formatString 格式化规则
     * @return String
     */
    public static String format(Date date, String formatString) {
        SimpleDateFormat sdf = new SimpleDateFormat(formatString);
        return sdf.format(date);
    }


    /**
     * 获取昨日日期
     *
     * @return 昨日
     */
    public static String getLastDayString() {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DATE, -1);
        return formatSimple(cal.getTime());
    }

    /**
     * 获取今日日期 字符串
     *
     * @return 今天
     */
    public static String getTodayString() {
        Calendar cal = Calendar.getInstance();
        return formatSimple(cal.getTime());
    }

    /**
     * 获取当天的开始时间
     *
     * @return date
     */
    public static Date getDayBegin() {
        Calendar cal = new GregorianCalendar();
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }


    /**
     * 获取当天的结束时间
     *
     * @return date
     */
    public static Date getDayEnd() {
        Calendar cal = new GregorianCalendar();
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        return cal.getTime();
    }

    /**
     * 获取昨天的开始时间
     *
     * @return date
     */

    public static Date getBeginDayOfYesterday() {
        Calendar cal = new GregorianCalendar();
        cal.setTime(getDayBegin());
        cal.add(Calendar.DAY_OF_MONTH, -1);
        return cal.getTime();
    }

    /**
     * 获取昨天的结束时间
     *
     * @return date
     */
    public static Date getEndDayOfYesterDay() {
        Calendar cal = new GregorianCalendar();
        cal.setTime(getDayEnd());
        cal.add(Calendar.DAY_OF_MONTH, -1);
        return cal.getTime();
    }

    /**
     * date转timestamp
     *
     * @param date date
     * @return timestamp
     */
    public static Timestamp date2Timestamp(Date date) {
        return new Timestamp(date.getTime());
    }

    /**
     * timestamp转date
     *
     * @param timestamp timestamp
     * @return date
     */
    public static Date timestamp2Date(Timestamp timestamp) {
        return new Date(timestamp.getTime());
    }

    /**
     * 获取今天的hour数
     *
     * @return int
     */

    public static int getTodayHour() {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(System.currentTimeMillis());
        return cal.get(Calendar.HOUR_OF_DAY);
    }

    /**
     * 获取上个月开始
     *
     * @return date
     */
    public static Date getBeginLastMonth() {
        Calendar cal = new GregorianCalendar();
        cal.setTime(getDayBegin());
        cal.set(Calendar.DAY_OF_MONTH, 1);
        cal.add(Calendar.MONTH, -1);
        return cal.getTime();
    }

    /**
     * 获取上个月结束
     *
     * @return date
     */
    public static Date getEndLastMonth() {
        Calendar cal = new GregorianCalendar();
        cal.setTime(getDayEnd());
        cal.set(Calendar.DAY_OF_MONTH, 1);
        cal.add(Calendar.DAY_OF_MONTH, -1);
        return cal.getTime();
    }

    /**
     * 获取上周周一开始
     *
     * @return Date
     */
    public static Date getBeginLastWeek() {
        Calendar cal = new GregorianCalendar();
        cal.setTime(getDayBegin());
        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        cal.add(Calendar.WEEK_OF_MONTH, -1);
        return cal.getTime();
    }

    /**
     * 获取上周周末结束
     * 注:老外礼拜天是第1天
     *
     * @return Date
     */
    public static Date getEndLastWeek() {
        Calendar cal = new GregorianCalendar();
        cal.setTime(getDayEnd());
        cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
        return cal.getTime();
    }

    /**
     * 昨日
     *
     * @return java.sql.date
     */
    public static java.sql.Date getLastSqlDay() {
        Date date = getBeginDayOfYesterday();
        return new java.sql.Date(date.getTime());
    }

    public static java.sql.Date date2SqlDay(Date date) {
        return new java.sql.Date(date.getTime());
    }

    /**
     * string 转java.sql.date
     *
     * @param dateString dateString
     * @return java.sql.date
     */
    public static java.sql.Date string2SqlDay(String dateString) {
        Date date = parseSimple(dateString);
        return new java.sql.Date(date.getTime());
    }


    /**
     * 获取指定日期的开始时间
     *
     * @return date
     */
    public static Date getBeginDay(String dateString) {
        Calendar cal = new GregorianCalendar();
        cal.setTime(parseSimple(dateString));
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }


    public static Date getEndDay(String dateString) {
        Calendar cal = new GregorianCalendar();
        cal.setTime(parseSimple(dateString));
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MILLISECOND, 59);
        return cal.getTime();
    }


    public static Timestamp getBeginTimestamp(String dateString) {
        Date date = getBeginDay(dateString);
        return date2Timestamp(date);
    }


    public static Timestamp getEndTimestamp(String dateString) {
        Date date = getEndDay(dateString);
        return date2Timestamp(date);
    }


    /**
     * 获取某段时这里写代码片间内的所有日期
     *
     * @param dBegin dBegin
     * @param dEnd   dEnd
     * @return List<Date>
     */
    public static List<Date> findDates(Date dBegin, Date dEnd) {
        List<Date> lDate = new ArrayList<>();
        lDate.add(dBegin);
        Calendar calBegin = Calendar.getInstance();
        // 使用给定的 Date 设置此 Calendar 的时间
        calBegin.setTime(dBegin);
        Calendar calEnd = Calendar.getInstance();
        // 使用给定的 Date 设置此 Calendar 的时间
        calEnd.setTime(dEnd);
        // 测试此日期是否在指定日期之后
        while (dEnd.after(calBegin.getTime())) {
            // 根据日历的规则，为给定的日历字段添加或减去指定的时间量
            calBegin.add(Calendar.DAY_OF_MONTH, 1);
            lDate.add(calBegin.getTime());
        }
        return lDate;
    }

    public static void main(String[] args) {
        java.sql.Date date = string2SqlDay("2019-09-23");
        System.out.println(date);
    }
}
